﻿using System;
using System.Collections.Generic;

using DflyingForum.Core.Data.Domain.Entities;
using DflyingForum.Core.Data.NHHelper;
using NHibernate;

namespace DflyingForum.Core.Repositories
{
    public class ModuleReposity : NHibernateRepository<Module, int>
    {
        public override int Save(Module module)
        {
            //父模块ID,不存在则默认为一级模块，即0；
            int pid = module.PID;
            if (pid > 0)
            {
                Module prevModule = GetParentModule(module);
                //如果存在父模块，层次递归++
                module.Depth = prevModule.Depth + 1;
            }
            //兄弟节点Sort值++
            module.Sort = GetMaxSortAtSiblings(pid) + 1;
            return base.Save(module);
        }
        /// <summary>
        /// 获取父模块
        /// </summary>
        public Module GetParentModule(Module module)
        {
            return base.FindBy(module.PID);
        }

        /// <summary>
        /// 移动版块
        /// </summary>
        public void MoveModule(int fromId, int toId)
        {
            //改变sort、交换pid、交换depth
            Module from = base.FindBy(fromId);
            Module to = base.FindBy(toId);
            this.MoveModule(from, to);
        }

        public void MoveModule(Module from, Module to)
        {
            int fromPid = from.PID;
            int toPid = to.PID;

            int fromSort = from.Sort;
            int toSort = to.Sort;

            int fromDepth = from.Depth;
            int toDepth = to.Depth;

            //交换sort、交换pid、交换depth
            from.PID = toPid;
            from.Sort = toSort;
            from.Depth = toDepth;

            to.PID = fromPid;
            to.Sort = fromSort;
            to.Depth = fromDepth;
            base.Update(from);
            base.Update(to);
        }

        /// <summary>
        /// 获取兄弟节点最大的Sort值
        /// </summary>
        private int GetMaxSortAtSiblings(int pid)
        {
            return _session.CreateCriteria<Module>()
                    .Add(NHibernate.Criterion.Expression.Eq("PID", pid))
                    .SetProjection(NHibernate.Criterion.Projections.Max("Sort"))
                    .UniqueResult<int>();
        }
    }
}